#ifndef ZDATABASE_INL
#define ZDATABASE_INL
#include <iomanip>
#include <iostream>
#include <sstream>

#include "ZDataBase.h"


template<typename StringType>
template<NDFrame::Field field>
StringType NDFrame::ZDataBase<StringType>::join(VecItemPtr &in_ptr, const StringType &Char_) {
    if (in_ptr.empty() || Char_.size() >= 2) {
        return {};
    }

    std::basic_ostringstream<typename StringType::value_type> oss;
    for (size_t i = 0; i < in_ptr.size(); ++i) {
        if (i != 0 && !Char_.empty()) {
            oss << Char_;
        }
        oss << getFieldText<field>(*in_ptr[i]);
    }
    return oss.str();
}

template<typename StringType>
bool NDFrame::ZDataBase<StringType>::ptr2_xyxy(VecItemPtr& inout_ptr,
                                               const std::function<bool(const DataItem<StringType>&)>& condition) {
	if (inout_ptr.empty()) return false;

	VecItemPtr filtered_pointers;
	filtered_pointers.reserve(inout_ptr.size());

	for (auto& index : inout_ptr) {
		if (condition(*index)) {
			filtered_pointers.push_back(index);
		}
	}

	inout_ptr = std::move(filtered_pointers);
	return !inout_ptr.empty();
}


template<typename StringType>
template<NDFrame::Field field>
const StringType& NDFrame::ZDataBase<StringType>::getField(const DataItem<StringType>& item) {
    if constexpr (field == Field::TEXT) {
        return item.text;
    } else if constexpr (field == Field::TEXT_SEP) {
        return item.text_sep;
    } else {
        throw std::invalid_argument("Invalid field");
    }
}


template<typename StringType>
template<NDFrame::Field field>
StringType NDFrame::ZDataBase<StringType>::getFieldText(DataItem<StringType>& item) {
    if constexpr (field == Field::TEXT) {
        return item.text;
    } else if constexpr (field == Field::TEXT_SEP) {
        return item.text_sep;
    } else {
        throw std::invalid_argument("Invalid field");
    }
}


template<typename StringType>
template<NDFrame::Field field>
bool NDFrame::ZDataBase<StringType>::ptr2_reg_impl_(VecItemPtr &inout_ptr, const VecRegex &regex_) {
    VecItemPtr filtered_pointers;
    filtered_pointers.reserve(inout_ptr.size());

    for (auto& index : inout_ptr) {
        const StringType& field_value = getField<field>(*index);
        for (const auto& reg : regex_) {
            if (matches_regex(field_value, reg)) {
                filtered_pointers.push_back(index);
                break;
            }
        }
    }

    inout_ptr = std::move(filtered_pointers);
    return !inout_ptr.empty();
}


template<typename StringType>
template<NDFrame::Field field>
bool NDFrame::ZDataBase<StringType>::ptr2_reg_common4(
        VecItemPtr& inout_ptr,
        const VecRegex& regex_, const int len,
	    const std::function<bool(size_t, size_t)>& compare) {

	if (inout_ptr.empty()) return false;

	VecItemPtr filtered_pointers;
	filtered_pointers.reserve(inout_ptr.size());

	for (auto& index : inout_ptr) {
		const StringType& field_value = getField<field>(*index);
		if (compare(field_value.size(), len)) {
			for (const auto& reg : regex_) {
				if (matches_regex(field_value, reg)) {
					filtered_pointers.push_back(index);
					break;
				}
			}
		}
	}
	inout_ptr = std::move(filtered_pointers);
	return !inout_ptr.empty();
}


template<typename StringType>
template<NDFrame::Field field>
bool NDFrame::ZDataBase<StringType>::ptr2_reg_common3(
        VecItemPtr& inout_ptr,
        const VecRegex& regex_,
	    const std::function<bool(const DataItem<StringType>&)>& condition) {

	if (inout_ptr.empty()) return false;

	VecItemPtr filtered_pointers;
	filtered_pointers.reserve(inout_ptr.size());

	for (auto& index : inout_ptr) {
		if (condition(*index)) {
			const StringType& field_value = getField<field>(*index);
			for (const auto& reg : regex_) {
				if (matches_regex(field_value, reg)) {
					filtered_pointers.push_back(index);
					break;
				}
			}
		}
	}

	inout_ptr = std::move(filtered_pointers);
	return !inout_ptr.empty();
}


template<typename StringType>
void NDFrame::ZDataBase<StringType>::print_data(const ZDataBase& data) {
	if (data.empty()) { return; }

	/* 预先定义表头的内容和宽度-> 计算每个字段的最大宽度 */
	std::vector<StringType> headers;
	const size_t size = data.size();
	std::vector<size_t> widths = { 6, 6, 6, 6, 6, 6, 6, 24, 8 };
	DataItem<StringType>* ItemPtr = nullptr;
	if constexpr (std::is_same_v<StringType, std::string>) {
		headers = { "idx", "x0", "y0", "x1", "y1", "width", "height", "text", "text_sep" };
		ItemPtr = data.getItemPtr();

		for (size_t i = 0; i < size; ++i) {
			widths[0] = std::max(widths[0], get_num_width<std::string>(ItemPtr[i].idx));
			widths[1] = std::max(widths[1], get_num_width<std::string>(ItemPtr[i].x0));
			widths[2] = std::max(widths[2], get_num_width<std::string>(ItemPtr[i].y0));
			widths[3] = std::max(widths[3], get_num_width<std::string>(ItemPtr[i].x1));
			widths[4] = std::max(widths[4], get_num_width<std::string>(ItemPtr[i].y1));
			widths[5] = std::max(widths[5], get_num_width<std::string>(ItemPtr[i].width));
			widths[6] = std::max(widths[6], get_num_width<std::string>(ItemPtr[i].height));
			widths[7] = std::max(widths[7], get_string_width<std::string>(ItemPtr[i].text));
			widths[8] = std::max(widths[8], get_string_width<std::string>(ItemPtr[i].text_sep));
		}
	}
	else if constexpr (std::is_same_v<StringType, std::wstring>) {
		headers = { L"idx", L"x0", L"y0", L"x1", L"y1", L"width", L"height", L"text", L"text_sep" };
		ItemPtr = data.getItemPtr();

		for (size_t i = 0; i < size; ++i) {
			widths[0] = std::max(widths[0], get_num_width<std::wstring>(ItemPtr[i].idx));
			widths[1] = std::max(widths[1], get_num_width<std::wstring>(ItemPtr[i].x0));
			widths[2] = std::max(widths[2], get_num_width<std::wstring>(ItemPtr[i].y0));
			widths[3] = std::max(widths[3], get_num_width<std::wstring>(ItemPtr[i].x1));
			widths[4] = std::max(widths[4], get_num_width<std::wstring>(ItemPtr[i].y1));
			widths[5] = std::max(widths[5], get_num_width<std::wstring>(ItemPtr[i].width));
			widths[6] = std::max(widths[6], get_num_width<std::wstring>(ItemPtr[i].height));
			widths[7] = std::max(widths[7], get_string_width<std::wstring>(ItemPtr[i].text));
			widths[8] = std::max(widths[8], get_string_width<std::wstring>(ItemPtr[i].text_sep));
		}
	}

	/* 打印表头*/
	if constexpr (std::is_same_v<StringType, std::string>) {
#if _WIN32
		std::cout.imbue(std::locale("zh_CN"));
#else
		std::locale::global(std::locale("zh_CN.UTF-8"));
		std::cout.imbue(std::locale("zh_CN.UTF-8"));
#endif
		std::ostringstream oss;
		print_separator(oss, widths, '=');
		oss << "| ";
		for (size_t i = 0; i < headers.size(); ++i) {
			oss << std::left << std::setw(to_int(widths[i])) << headers[i] << " | ";
		}
		oss << std::endl;
		print_separator(oss, widths, '=');

		/* 打印数据*/
		if (!ItemPtr) { return; }
		for (size_t i = 0; i < size; ++i) {
			oss << "| "
				<< std::setw(to_int(widths[0])) << format_number<std::string>(ItemPtr[i].idx) << " | "
				<< std::setw(to_int(widths[1])) << format_number<std::string>(ItemPtr[i].x0) << " | "
				<< std::setw(to_int(widths[2])) << format_number<std::string>(ItemPtr[i].y0) << " | "
				<< std::setw(to_int(widths[3])) << format_number<std::string>(ItemPtr[i].x1) << " | "
				<< std::setw(to_int(widths[4])) << format_number<std::string>(ItemPtr[i].y1) << " | "
				<< std::setw(to_int(widths[5])) << format_number<std::string>(ItemPtr[i].width) << " | "
				<< std::setw(to_int(widths[6])) << format_number<std::string>(ItemPtr[i].height) << " | "
				<< std::left << std::setw(to_int(widths[7])) << ItemPtr[i].text << " | "
				<< std::left << std::setw(to_int(widths[8])) << ItemPtr[i].text_sep
#if _WIN32
				<< " |\r\n";
#else
				<< " |\n";
#endif
		}

		print_separator(oss, widths, '-');
		std::cout << oss.str();
	}
	else if constexpr (std::is_same_v<StringType, std::wstring>) {
#if _WIN32
		std::wcout.imbue(std::locale("zh_CN"));
#else
		std::locale::global(std::locale("zh_CN.UTF-8"));
		std::wcout.imbue(std::locale("zh_CN.UTF-8"));
#endif
		std::wostringstream oss;
		print_separator(oss, widths, L'=');
		oss << L"| ";
		for (size_t i = 0; i < headers.size(); ++i) {
			oss << std::left << std::setw(to_int(widths[i])) << headers[i] << L" | ";
		}
		oss << std::endl;

		print_separator(oss, widths, L'=');

		/* 打印数据*/
		if (!ItemPtr) { return; }
		for (size_t i = 0; i < size; ++i) {
			oss << L"| " << std::setw(to_int(widths[0]))
				<< format_number<std::wstring>(ItemPtr[i].idx) << L" | "
				<< std::setw(to_int(widths[1])) << format_number<std::wstring>(ItemPtr[i].x0) << L" | "
				<< std::setw(to_int(widths[2])) << format_number<std::wstring>(ItemPtr[i].y0) << L" | "
				<< std::setw(to_int(widths[3])) << format_number<std::wstring>(ItemPtr[i].x1) << L" | "
				<< std::setw(to_int(widths[4])) << format_number<std::wstring>(ItemPtr[i].y1) << L" | "
				<< std::setw(to_int(widths[5])) << format_number<std::wstring>(ItemPtr[i].width) << L" | "
				<< std::setw(to_int(widths[6])) << format_number<std::wstring>(ItemPtr[i].height) << L" | "
				<< std::left << std::setw(to_int(widths[7])) << ItemPtr[i].text << L" | "
				<< std::left << std::setw(to_int(widths[8])) << ItemPtr[i].text_sep
#if _WIN32
				<< L" |\r\n";
#else
				<< L" |\n";
#endif
		}

		print_separator(oss, widths, L'-');
		std::wcout << oss.str();
	}
}



template<typename StringType>
StringType NDFrame::format_number(const int value) {
	static_assert(std::is_same_v<StringType, std::string> || std::is_same_v<StringType, std::wstring>,
			"StringType must be either std::string or std::wstring");
	if constexpr (std::is_same_v<StringType, std::string>) {
		return std::to_string(value);
	}
	else if constexpr (std::is_same_v<StringType, std::wstring>) {
		return std::to_wstring(value);
	}
	return StringType();
}



template<typename StringType>
size_t NDFrame::get_num_width(const int number) {
	return NDFrame::format_number<StringType>(number).size();
}


template<typename StringType>
size_t NDFrame::get_string_width(const StringType& str) {
	int width = 0;
	if constexpr (std::is_same_v<StringType, std::string>) {
		for (const char c : str) {
			if (static_cast<unsigned char>(c) < 0x80) {
				width += 1; // ASCII字符计算单倍宽度
			}
			else {
				width += 2; // 假设所有非ASCII字符占用双倍宽度
			}
		}
	}
	else if constexpr (std::is_same_v<StringType, std::wstring>) {
		for (const wchar_t c : str) {
			if (c < 0x80) {
				width += 1; // ASCII字符计算单倍宽度
			}
			else {
				width += 2; // 假设所有非ASCII字符占用双倍宽度
			}
		}
	}
	else {
		static_assert(std::is_same_v<StringType, std::string> || std::is_same_v<StringType, std::wstring>,
			"StringType must be either std::string or std::wstring");
	}
	return width;
}



template<typename StreamType>
void NDFrame::print_separator(StreamType& os, const std::vector<size_t>& widths, typename StreamType::char_type separator) {
	os << static_cast<typename StreamType::char_type>('+');
	for (const size_t width : widths) {
		os << std::basic_string<typename StreamType::char_type>(width + 2, separator)
			<< static_cast<typename StreamType::char_type>('+');
	}
	os << std::endl;
}


template<typename StringType>
void NDFrame::format_print(const ZDataBase<StringType>& database) {
	if (database.empty()) {
		return;
	}

	/* 预先定义表头的内容和宽度 -> 计算每个字段的最大宽度 */
	std::vector<StringType> headers;
	std::vector<size_t> widths = { 6, 6, 6, 6, 6, 6, 6, 24, 8 };
	DataItem<StringType>* ItemPtr = nullptr;
	const size_t size = database.size();
	if constexpr (std::is_same_v<StringType, std::string>) {
		ItemPtr = database.getItemPtr();
		headers = { "idx", "x0", "y0", "x1", "y1", "width", "height", "text", "text_sep" };

		for (size_t i = 0; i < size; ++i) {
			widths[0] = std::max(widths[0], get_num_width<std::string>(ItemPtr[i].idx));
			widths[1] = std::max(widths[1], get_num_width<std::string>(ItemPtr[i].x0));
			widths[2] = std::max(widths[2], get_num_width<std::string>(ItemPtr[i].y0));
			widths[3] = std::max(widths[3], get_num_width<std::string>(ItemPtr[i].x1));
			widths[4] = std::max(widths[4], get_num_width<std::string>(ItemPtr[i].y1));
			widths[5] = std::max(widths[5], get_num_width<std::string>(ItemPtr[i].width));
			widths[6] = std::max(widths[6], get_num_width<std::string>(ItemPtr[i].height));
			widths[7] = std::max(widths[7], get_string_width(ItemPtr[i].text));
			widths[8] = std::max(widths[8], get_string_width(ItemPtr[i].text_sep));
		}
	}
	else if constexpr (std::is_same_v<StringType, std::wstring>) {
		ItemPtr = database.getItemPtr();
		headers = { L"idx", L"x0", L"y0", L"x1", L"y1", L"width", L"height", L"text", L"text_sep" };

		for (size_t i = 0; i < size; ++i) {
			widths[0] = std::max(widths[0], get_num_width<std::wstring>(ItemPtr[i].idx));
			widths[1] = std::max(widths[1], get_num_width<std::wstring>(ItemPtr[i].x0));
			widths[2] = std::max(widths[2], get_num_width<std::wstring>(ItemPtr[i].y0));
			widths[3] = std::max(widths[3], get_num_width<std::wstring>(ItemPtr[i].x1));
			widths[4] = std::max(widths[4], get_num_width<std::wstring>(ItemPtr[i].y1));
			widths[5] = std::max(widths[5], get_num_width<std::wstring>(ItemPtr[i].width));
			widths[6] = std::max(widths[6], get_num_width<std::wstring>(ItemPtr[i].height));
			widths[7] = std::max(widths[7], get_string_width(ItemPtr[i].text));
			widths[8] = std::max(widths[8], get_string_width(ItemPtr[i].text_sep));
		}
	}


	/* 打印表头*/
	if constexpr (std::is_same_v<StringType, std::string>) {
#if _WIN32
		std::cout.imbue(std::locale("zh_CN"));
#else
		std::locale::global(std::locale("zh_CN.UTF-8"));
		std::cout.imbue(std::locale("zh_CN.UTF-8"));
#endif
		std::ostringstream oss;
		print_separator(oss, widths, '=');
		oss << "| ";
		for (size_t i = 0; i < headers.size(); ++i) {
			oss << std::left << std::setw(to_int(widths[i])) << headers[i] << " | ";
		}
		oss << std::endl;
		print_separator(oss, widths, '=');

		/* 打印数据*/
		if (!ItemPtr) { return; }
		for (size_t i = 0; i < size; ++i) {
			oss << "| " << std::setw(to_int(widths[0])) << format_number<std::string>(ItemPtr[i].idx)
				<< " | "
				<< std::setw(to_int(widths[1])) << format_number<std::string>(ItemPtr[i].x0) << " | "
				<< std::setw(to_int(widths[2])) << format_number<std::string>(ItemPtr[i].y0) << " | "
				<< std::setw(to_int(widths[3])) << format_number<std::string>(ItemPtr[i].x1) << " | "
				<< std::setw(to_int(widths[4])) << format_number<std::string>(ItemPtr[i].y1) << " | "
				<< std::setw(to_int(widths[5])) << format_number<std::string>(ItemPtr[i].width) << " | "
				<< std::setw(to_int(widths[6])) << format_number<std::string>(ItemPtr[i].height) << " | "
				<< std::left << std::setw(to_int(widths[7])) << ItemPtr[i].text << " | "
				<< std::left << std::setw(to_int(widths[8])) << ItemPtr[i].text_sep
#if _WIN32
				<< " |\r\n";
#else
				<< " |\n";
#endif
		}

		print_separator(oss, widths, '-');
		std::cout << oss.str();
	}
	else if constexpr (std::is_same_v<StringType, std::wstring>) {
#if _WIN32
		std::wcout.imbue(std::locale("zh_CN"));
#else
		std::locale::global(std::locale("zh_CN.UTF-8"));
		std::wcout.imbue(std::locale("zh_CN.UTF-8"));
#endif
		std::wostringstream oss;
		print_separator(oss, widths, L'=');
		oss << L"| ";
		for (size_t i = 0; i < headers.size(); ++i) {
			oss << std::left << std::setw(to_int(widths[i])) << headers[i] << L" | ";
		}
		oss << std::endl;

		print_separator(oss, widths, L'=');

		/* 打印数据*/
		if (!ItemPtr) { return; }
		for (size_t i = 0; i < size; ++i) {
			oss << L"| " << std::setw(to_int(widths[0])) << format_number<std::wstring>(ItemPtr[i].idx)
				<< L" | "
				<< std::setw(to_int(widths[1])) << format_number<std::wstring>(ItemPtr[i].x0) << L" | "
				<< std::setw(to_int(widths[2])) << format_number<std::wstring>(ItemPtr[i].y0) << L" | "
				<< std::setw(to_int(widths[3])) << format_number<std::wstring>(ItemPtr[i].x1) << L" | "
				<< std::setw(to_int(widths[4])) << format_number<std::wstring>(ItemPtr[i].y1) << L" | "
				<< std::setw(to_int(widths[5])) << format_number<std::wstring>(ItemPtr[i].width) << L" | "
				<< std::setw(to_int(widths[6])) << format_number<std::wstring>(ItemPtr[i].height)
				<< L" | "
				<< std::left << std::setw(to_int(widths[7])) << ItemPtr[i].text << L" | "
				<< std::left << std::setw(to_int(widths[8])) << ItemPtr[i].text_sep
#if _WIN32
				<< L" |\r\n";
#else
				<< L" |\n";
#endif
		}

		print_separator(oss, widths, L'-');
		std::wcout << oss.str();
	}
}


template<typename StringType>
void NDFrame::format_print(const ZDataBase<StringType>* dataframe) {
	if (dataframe == nullptr || dataframe->empty()) {
		return;
	}
	format_print(*dataframe);
}


template<typename StringType>
void NDFrame::format_print(const std::vector<DataItem<StringType>*>& pointers) {
	if (pointers.empty()) {return; }

	/* 预先定义表头的内容和宽度 -> 计算每个字段的最大宽度*/
	std::vector<StringType> headers;
	std::vector<size_t> widths = { 6, 6, 6, 6, 6, 6, 6, 24, 8 };
	size_t size = pointers.size();
	if constexpr (std::is_same_v<StringType, std::string>) {
		headers = { "idx", "x0", "y0", "x1", "y1", "width", "height", "text", "text_sep" };

		for (size_t i = 0; i < size; ++i) {
			widths[0] = std::max(widths[0], get_num_width<std::string>(pointers[i]->idx));
			widths[1] = std::max(widths[1], get_num_width<std::string>(pointers[i]->x0));
			widths[2] = std::max(widths[2], get_num_width<std::string>(pointers[i]->y0));
			widths[3] = std::max(widths[3], get_num_width<std::string>(pointers[i]->x1));
			widths[4] = std::max(widths[4], get_num_width<std::string>(pointers[i]->y1));
			widths[5] = std::max(widths[5], get_num_width<std::string>(pointers[i]->width));
			widths[6] = std::max(widths[6], get_num_width<std::string>(pointers[i]->height));
			widths[7] = std::max(widths[7], get_string_width<std::string>(pointers[i]->text));
			widths[8] = std::max(widths[8], get_string_width<std::string>(pointers[i]->text_sep));
		}
	}
	else if constexpr (std::is_same_v<StringType, std::wstring>) {
		headers = { L"idx", L"x0", L"y0", L"x1", L"y1", L"width", L"height", L"text", L"text_sep" };

		for (size_t i = 0; i < size; ++i) {
			widths[0] = std::max(widths[0], get_num_width<std::wstring>(pointers[i]->idx));
			widths[1] = std::max(widths[1], get_num_width<std::wstring>(pointers[i]->x0));
			widths[2] = std::max(widths[2], get_num_width<std::wstring>(pointers[i]->y0));
			widths[3] = std::max(widths[3], get_num_width<std::wstring>(pointers[i]->x1));
			widths[4] = std::max(widths[4], get_num_width<std::wstring>(pointers[i]->y1));
			widths[5] = std::max(widths[5], get_num_width<std::wstring>(pointers[i]->width));
			widths[6] = std::max(widths[6], get_num_width<std::wstring>(pointers[i]->height));
			widths[7] = std::max(widths[7], get_string_width<std::wstring>(pointers[i]->text));
			widths[8] = std::max(widths[8], get_string_width<std::wstring>(pointers[i]->text_sep));
		}
	}

	/* 打印表头*/
	if constexpr (std::is_same_v<StringType, std::string>) {
#if _WIN32
		std::cout.imbue(std::locale("zh_CN"));
#else
		std::locale::global(std::locale("zh_CN.UTF-8"));
		std::cout.imbue(std::locale("zh_CN.UTF-8"));
#endif
		std::ostringstream oss;
		print_separator(oss, widths, '=');
		oss << "| ";
		for (size_t i = 0; i < headers.size(); ++i) {
			oss << std::left << std::setw(to_int(widths[i])) << headers[i] << " | ";
		}
		oss << std::endl;

		print_separator(oss, widths, '=');
		/* 打印数据*/

		for (size_t i = 0; i < size; ++i) {
			oss << "| " << std::setw(to_int(widths[0])) << format_number<std::string>(pointers[i]->idx)
				<< " | "
				<< std::setw(to_int(widths[1])) << format_number<std::string>(pointers[i]->x0) << " | "
				<< std::setw(to_int(widths[2])) << format_number<std::string>(pointers[i]->y0) << " | "
				<< std::setw(to_int(widths[3])) << format_number<std::string>(pointers[i]->x1) << " | "
				<< std::setw(to_int(widths[4])) << format_number<std::string>(pointers[i]->y1) << " | "
				<< std::setw(to_int(widths[5])) << format_number<std::string>(pointers[i]->width) << " | "
				<< std::setw(to_int(widths[6])) << format_number<std::string>(pointers[i]->height) << " | "
				<< std::left << std::setw(to_int(widths[7])) << pointers[i]->text << " | "
				<< std::left << std::setw(to_int(widths[8])) << pointers[i]->text_sep
#if _WIN32
				<< " |\r\n";
#else
				<< " |\n";
#endif
		}
		print_separator(oss, widths, '-');
		std::cout << oss.str() << std::flush;
	}
	else if constexpr (std::is_same_v<StringType, std::wstring>) {
#if _WIN32
		std::wcout.imbue(std::locale("zh_CN"));
#else
		std::locale::global(std::locale("zh_CN.UTF-8"));
		std::wcout.imbue(std::locale("zh_CN.UTF-8"));
#endif
		std::wostringstream oss;
		print_separator(oss, widths, L'=');
		oss << L"| ";
		for (size_t i = 0; i < headers.size(); ++i) {
			oss << std::left << std::setw(to_int(widths[i])) << headers[i] << L" | ";
		}
		oss << std::endl;

		print_separator(oss, widths, L'=');

		/* 打印数据*/
		for (size_t i = 0; i < size; ++i) {
			oss << L"| " << std::setw(to_int(widths[0])) << format_number<std::wstring>(pointers[i]->idx)
				<< L" | "
				<< std::setw(to_int(widths[1])) << format_number<std::wstring>(pointers[i]->x0) << L" | "
				<< std::setw(to_int(widths[2])) << format_number<std::wstring>(pointers[i]->y0) << L" | "
				<< std::setw(to_int(widths[3])) << format_number<std::wstring>(pointers[i]->x1) << L" | "
				<< std::setw(to_int(widths[4])) << format_number<std::wstring>(pointers[i]->y1) << L" | "
				<< std::setw(to_int(widths[5])) << format_number<std::wstring>(pointers[i]->width) << L" | "
				<< std::setw(to_int(widths[6])) << format_number<std::wstring>(pointers[i]->height) << L" | "
				<< std::left << std::setw(to_int(widths[7])) << pointers[i]->text << L" | "
				<< std::left << std::setw(to_int(widths[8])) << pointers[i]->text_sep
#if _WIN32
				<< L" |\r\n";
#else
				<< L" |\n";
#endif
		}

		print_separator(oss, widths, '-');
		std::wcout << oss.str() << std::flush;
	}
}




#endif